import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import App from '@/App.vue'

// 引入moment时间处理插件
import moment from 'moment'

// 引入全局样式
import '@/assets/style/global.css'

import creatRouter from '@/config/router.js'
import createStore from '@/store/store.js'

let time = moment().format('dddd')
console.log(time)

console.log(process.env.NODE_ENV)

// let root = document.createElement('div')
// document.body.appendChild(root)
// app.$mount(root)

Vue.use(VueRouter)
Vue.use(Vuex)

let router = creatRouter()
let store = createStore()

// 动态注册store模块
store.registerModule('a', {
  state: {
    text: 1
  }
})

// 解绑
// store.unregisterModule('a')

// 当第一个函数的返回值变化时，执行第二个函数，第二个函数的参数是第一个函数的返回值
// store.watch(
//   state => state.count + 1,
//   newCount => {
//     console.log('newCount:', newCount)
//   }
// )

// 当调用mutation时触发
// store.subscribe((mutation, state) => {
//   console.log(mutation.type)
//   console.log(mutation.payload)
// })

// 当调用action时触发
// store.subscribeAction((action, state) => {
//   console.log(action.type)
//   console.log(action.payload)
// })

router.beforeEach((to, from, next) => {
  console.log('beforeEach')
  next()
})

router.beforeResolve((to, from, next) => {
  console.log('beforeResolve')
  next()
})

router.afterEach(() => {
  console.log('afterEach')
})

let app = new Vue({
  name: 'Root',
  router,
  store,
  data: {
    value: 0
  },
  provide () {
    // vue 的 provide 提供的属性不会自动双向绑定，需要手动实现双向绑定（官方并不推荐使用，可能以后的版本会改掉）
    const data = {}
    Object.defineProperty(data, 'value', {
      get: () => {
        return this.value
      },
      enumerable: true
    })

    return {
      root: this,
      data
    }
  },
  render (c) {
    return c(App)
  }
})
app.$mount('#app')

// ----------------------------------------------
// let component = {
//   parent: 'comParent', // 在组件内部配置parent不生效
//   model: { // 自定义组件的双向绑定接受的prop的名字和触发的事件
//     prop: 'value1',
//     event: 'change'
//   },
//   props: ['value1'],
//   mounted () {
//     console.log('outer')
//   }
// }

// const parent = new Vue({
//   name: 'parent'
// })

// const CompVue = Vue.extend(component)

// let app = new CompVue({
//   // propsData:[],
//    provide(){ // 暴漏给子组件，自组件可以使用inject引用
//    return {
//        'yeye': this
// }
// }
//   parent: parent, // 只有在new的时候才能指定parent的配置项
//   name: 'root',
//   mounted () {
//     console.log('inner')
//     console.log(this.$parent.$options.name)
//   },
//   render (c) {
//     return c(App)
//   }
// })
// app.$mount('#app')
// --------------------------------------------
// let app = new Vue({
//   template: '<div ref="a">{{a}}{{obj.a}}</div>',
//   // render (h) { // 在beforeMount和mounted之间执行
//   //   // throw new TypeError('render error')
//   //   return h('div', {}, `${this.a} ${this.obj.a || ''}`)
//   // },
//   // 只有在本组件捕获错误，正式环境不回被调用
//   // renderError (h, err) {
//   //   return h('div', {}, err.stack)
//   // },
//   // 可以捕获子组件报的错误，正式环境可以使用
//   // errorCaptured () {},
//   data () {
//     return {
//       a: 0,
//       obj: { a: 0 }
//     }
//   },
//   watch: {
//     a: {
//       handler (n, o) {
//         console.log(n, o)
//       },
//       immediate: true // 进入组件立即执行
//     },
//     // a (n, o) {
//     //   console.log(n, o)
//     // }
//     obj: {
//       handler (n, o) {
//         console.log(n, o)
//       },
//       deep: true // 可以监听对象内部的属性，更改obj.a的值
//     }
//     // 或者
//     // 'obj.a': {
//     //   handler (n, o) {
//     //     console.log(n, o)
//     //   }
//     // }
//   }
// })

// app.$mount('#app')
// setTimeout(() => {
//   // app.obj.a = 999
//   // app.$forceUpdate() // 强制渲染
//   // 或者
//   // app.$set(app.obj, 'a', 999)
//   // app.$delete(app.obj, 'a')
// }, 2000)

// console.log(app.$data, app.$props)
// console.log(app.$el)
// console.log(app.$options)
// 当下一次值变化时会触发这个render方法
// app.$options.render = function (h) {
//   return h('div', {}, 'this is render function')
// }
// console.log(app.$root === app) // true
// console.log(app.$children, app.$parent)
// console.log(app.$slots, app.$scopedSlots)
// console.log(app.$refs)
// console.log(app.$isServer)
// const unWacht = app.$watch('a', (n, o) => {
//   console.log(n, o)
// })
// unWatch() // 取消监听
// 只触发一次
// app.$once('test', (a, b) => {
//   console.log('触发了', a, b)
// })
// // 可以触发多次
// app.$on('test', (a, b) => {
//   console.log('触发了', a, b)
// })
// app.$emit('test', 1, 2)
// app.$forceUpdate()
// app.$destroy() // 销毁当前组件
// -------------------------------------------
